using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace SmartDeviceProject1
{
    public partial class Form1 : Form
    {
        [DllImport("S8ce.dll", EntryPoint = "fw_init")]
        public static extern Int32 fw_init(Int16 port, Int32 baud);
        [DllImport("S8ce.dll", EntryPoint = "fw_config_card")]
        public static extern Int32 fw_config_card(Int32 icdev, Byte flags);
        [DllImport("S8ce.dll", EntryPoint = "fw_exit")]
        public static extern Int32 fw_exit(Int32 icdev);
        [DllImport("S8ce.dll", EntryPoint = "fw_card")]
        public static extern Int32 fw_card(Int32 icdev, Byte _Mode, ulong[]  _Snr);
        [DllImport("S8ce.dll", EntryPoint = "fw_load_key")]
        public static extern Int32 fw_load_key(Int32 icdev, Byte _Mode, Byte _SecNr,  Byte[] _NKey);
        [DllImport("S8ce.dll", EntryPoint = "fw_authentication")]
        public static extern Int32 fw_authentication(Int32 icdev, Byte _Mode, Byte _SecNr);
        [DllImport("S8ce.dll", EntryPoint = "fw_read")]
        public static extern Int32 fw_read(Int32 icdev, Byte _Adr,  Byte[] _Data);

        [DllImport("umf.dll", EntryPoint = "fw_read_hex")]
        public static extern Int16 fw_read_hex(Int32 icdev, Byte _Adr, StringBuilder _Data);

        [DllImport("S8ce.dll", EntryPoint = "fw_write")]
        public static extern Int32 fw_write(Int32 icdev, Byte _Adr,  Byte[] _Data);

        [DllImport("umf.dll", EntryPoint = "fw_write_hex")]
        public static extern Int16 fw_write_hex(Int32 icdev, Byte _Adr, string _Data);

        [DllImport("S8ce.dll", EntryPoint = "fw_halt")]
        public static extern Int32 fw_halt(Int32 icdev);
        [DllImport("S8ce.dll", EntryPoint = "fw_changeb3")]
        public static extern Int32 fw_changeb3(Int32 icdev, Byte _SecNr,  Byte[] _KeyA,  Byte[] _CtrlW, Byte _Bk,
                 Byte[] _KeyB);
        [DllImport("S8ce.dll", EntryPoint = "fw_initval")]
        public static extern Int32 fw_initval(Int32 icdev, Byte _Adr, UInt32 _Value);
        [DllImport("S8ce.dll", EntryPoint = "fw_increment")]
        public static extern Int32 fw_increment(Int32 icdev, Byte _Adr, UInt32 _Value);
        [DllImport("S8ce.dll", EntryPoint = "fw_readval")]
        public static extern Int32 fw_readval(Int32 icdev, Byte _Adr,  UInt32[] _Value);
        [DllImport("S8ce.dll", EntryPoint = "fw_decrement")]
        public static extern Int32 fw_decrement(Int32 icdev, Byte _Adr, UInt32 _Value);
        [DllImport("S8ce.dll", EntryPoint = "fw_restore")]
        public static extern Int32 fw_restore(Int32 icdev, Byte _Adr);
        [DllImport("S8ce.dll", EntryPoint = "fw_transfer")]
        public static extern Int32 fw_transfer(Int32 icdev, Byte _Adr);
        [DllImport("S8ce.dll", EntryPoint = "fw_beep")]
        public static extern Int32 fw_beep(Int32 icdev, UInt32 _Msec);
        [DllImport("S8ce.dll", EntryPoint = "fw_getver")]
        public static extern Int32 fw_getver(Int32 icdev,  Byte[] buff);
        [DllImport("S8ce.dll", EntryPoint = "fw_reset")]
        public static extern Int16 fw_reset(Int32 icdev, UInt16 _Msec);
        [DllImport("S8ce.dll", EntryPoint = "hex_a")]
        public static extern void hex_a( Byte[] hex,  Byte[] a, Int16 len);
        [DllImport("S8ce.dll", EntryPoint = "a_hex")]
        public static extern Int32 a_hex(Byte[] a, Byte[] hex, Int16 len);

        string gl_strMsg;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int blk = 0;

            for (blk = 0; blk < 64; blk++)
                combo_blk.Items.Add(blk);

            combo_blk.SelectedIndex = 1;
            combo_port.SelectedIndex = 0;
            combo_baud.SelectedIndex = 1;
        }

        private void combo_blk_SelectedValueChanged(object sender, EventArgs e)
        {
            int iCurSel;

            iCurSel = combo_blk.SelectedIndex;

            if (iCurSel % 4 == 3 || iCurSel == 0)
            {
                btn_write.Enabled = false;
            }
            else
                btn_write.Enabled = true;
        }

        private int getCurPort()
        {
            return combo_port.SelectedIndex;
        }
        private int getCurBaud()
        {
            return Int32.Parse(combo_baud.SelectedItem.ToString());
        }
        private int getCurBlock()
        {
            return combo_blk.SelectedIndex;
        }

        private void ShowMsg(string strmsg)
        {
            gl_strMsg += strmsg;
            gl_strMsg += "\r\n";

            tb_msg.Text = gl_strMsg;
        }

        private void btn_read_Click(object sender, EventArgs e)
        {
            Int32 icdev;
            Int16 port;
            Int32 baud;
            Int32 opStatus; 
            byte  anthenMode = 0;
            byte  findMode = 1;
            byte  t_blk, t_sector;
            Byte[] defKey = {0xff,0xff,0xff, 0xff,0xff,0xff};
            ulong[] snrArr = new ulong[2];
            Byte[] bufData = new Byte[128];
            Byte[] szData = new Byte[128];

            port = (short)getCurPort();
            baud = getCurBaud();
            t_blk = (byte)getCurBlock ();
            t_sector = (byte)(t_blk / 4);

            gl_strMsg = "";

            //link reader
            icdev = fw_init(port, baud);

            if (-1 == icdev)
            {
                ShowMsg("Link reader failed");
                return;
            }

            ShowMsg("link reader ok");

            //load key
            opStatus = fw_load_key(icdev, anthenMode, t_sector, defKey);
            if (opStatus != 0)
            {
                ShowMsg("fw_load_keyfailed");
                fw_exit(icdev);
                return;
            }

            ShowMsg("fw_load_key ok");

            //find card
            opStatus = fw_card(icdev, findMode, snrArr);
             if (opStatus != 0)
            {
                ShowMsg("fw_card failed");
                fw_exit(icdev);
                return;
            }
            ShowMsg("fw_card ok, sn: "+ snrArr[0].ToString ());

            //authen
            opStatus = fw_authentication(icdev, anthenMode, t_sector);
            if (opStatus != 0)
            {
                ShowMsg("fw_authentication failed");
                fw_exit(icdev);
                return;
            }
            ShowMsg("fw_authentication ok");

            //read data
            opStatus = fw_read(icdev, t_blk,  bufData);
            if (opStatus != 0)
            {
                ShowMsg("fw_read failed");
                fw_exit(icdev);
                return;
            }
            ShowMsg("fw_read ok");

            hex_a(szData, bufData, 32);
            tb_data.Text = System.Text.Encoding.Default.GetString(szData,0, 32);

            fw_exit(icdev);
        }

        private void btn_write_Click(object sender, EventArgs e)
        {
            Int32 icdev;
            Int16 port;
            Int32 baud;
            Int32 opStatus;
            byte anthenMode = 0;
            byte findMode = 1;
            byte t_blk, t_sector;
            Byte[] defKey = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
            ulong[] snrArr = new ulong[2];
            Byte[] bufData = new Byte[128];
            Byte[] szData = new Byte[128];
            string w_data;

            port = (short)getCurPort();
            baud = getCurBaud();
            t_blk = (byte)getCurBlock();
            t_sector = (byte)(t_blk / 4);

            gl_strMsg = "";

            //link reader
            icdev = fw_init(port, baud);

            if (-1 == icdev)
            {
                ShowMsg("Link reader failed");
                return;
            }

            ShowMsg("link reader ok");

            //load key
            opStatus = fw_load_key(icdev, anthenMode, t_sector, defKey);
            if (opStatus != 0)
            {
                ShowMsg("fw_load_keyfailed");
                fw_exit(icdev);
                return;
            }

            ShowMsg("fw_load_key ok");

            //find card
            opStatus = fw_card(icdev, findMode, snrArr);
            if (opStatus != 0)
            {
                ShowMsg("fw_card failed");
                fw_exit(icdev);
                return;
            }
            ShowMsg("fw_card ok, sn: " + snrArr[0].ToString());

            //authen
            opStatus = fw_authentication(icdev, anthenMode, t_sector);
            if (opStatus != 0)
            {
                ShowMsg("fw_authentication failed");
                fw_exit(icdev);
                return;
            }
            ShowMsg("fw_authentication ok");

            //write data
            w_data = tb_data.Text.ToString();
            if (w_data.Length != 32)
            {
                ShowMsg("Invalid data for writting");
                fw_exit(icdev);
                return;
            }
            szData = System.Text.Encoding.Default.GetBytes(w_data);
            a_hex(bufData, szData, 16);

            opStatus = fw_write(icdev, t_blk, bufData);
            if (opStatus != 0)
            {
                ShowMsg("fw_write failed");
                fw_exit(icdev);
                return;
            }
            ShowMsg("fw_write ok");

            fw_exit(icdev);
        }


    }
}